package cn.com.hhrcw.web;

import cn.com.hhrcw.constant.CodeVConstant;
import cn.com.hhrcw.constant.CommonConstant;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.PiInfoConvert;
import cn.com.hhrcw.mapstruct.SysPersonAnnouncementConvert;
import cn.com.hhrcw.params.LoginUserParams;
import cn.com.hhrcw.params.PiInfoParams;
import cn.com.hhrcw.params.SysPersonAnnouncementParams;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.sms.service.ISysSmsTemplateService;
import cn.com.hhrcw.utils.AgeUtil;
import cn.com.hhrcw.utils.SubjectUtils;
import cn.com.hhrcw.utils.edu.EduLabelUtil;
import cn.com.hhrcw.vo.PiInfoNumVO;
import cn.com.hhrcw.vo.PiInfoVO;
import cn.com.hhrcw.vo.SysPersonAnnouncementVO;
import cn.com.hhrcw.vo.UserResumeFlagVO;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Charsets;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.base.entity.AttributesValueParams;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * 个人基本信息
 *
 * @author jiangdong
 * @since 2020-10-29
 */
@RestController
@Slf4j
@RequestMapping("/personal/v1/piInfo")
@Api(tags = "个人基本信息")
@Validated
public class PiInfoController extends JeecgController<PiInfo, IPiInfoService> {
    @Value("${spring.profiles.active}")
    private String profiles;

    /**
     * 测试环境
     */
    private static final String TEST = "test";

    /**
     * 开发环境
     */
    private static final String DEV = "dev";

    @Autowired
    private ISysSmsTemplateService sysSmsTemplateService;

    @Autowired
    private IPiInfoService pinfoService;

    @Autowired
    SysAnnouncementService sysAnnouncementService;

    @Autowired
    SysPersonAnnouncementConvert sysPersonAnnouncementConvert;

    @Autowired
    private EduLabelUtil eduLabelUtil;

    @Autowired
    private PiInfoConvert piInfoConvert;

    @Autowired
    private IOpCollectionService collectionService;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private ICvUserEduInfoService userEduInfoService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ICvResumeService cvResumeService;

    /**
     * 分页列表查询
     *
     * @param params 请求参数
     * @return
     */
    @GetMapping(value = "/list")
    @AutoLog("个人基本信息-分页列表查询")
    @ApiOperation(value = "分页列表查询", notes = "分页列表查询")
    @PermissionData
    public Result<Page<PiInfoVO>> list(PiInfoParams params, HttpServletRequest request) {
        QueryWrapper<PiInfo> queryWrapper = QueryGenerator.initQueryWrapper(piInfoConvert.toEntity(params), request.getParameterMap());
        queryWrapper.eq("del_flag", false);
        if (StringUtils.isBlank(params.getField())) {
            queryWrapper.orderByDesc("create_time");
        } else {
            queryWrapper.orderBy(true, params.getSort(), toUnderlineName(params.getField()));
        }
        IPage<PiInfo> page = pinfoService.page(params.page(), queryWrapper);
        //分页结果转换器
        Function<PiInfo, PiInfoVO> fun = piInfo -> piInfoConvert.toVO(piInfo);

        return Result.ok((Page) page.convert(fun));
    }

    /**
     * 个人是否能够投简历
     *
     * @param
     * @return
     */
    @PostMapping(value = "/resumeFlag")
    @AutoLog("个人是否能够投简历")
    public Result<?> userFlag() {
        UserResumeFlagVO vo = new UserResumeFlagVO();

        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        String userId = sysUser.getId();
        sysBaseApi.addLog(userId);
        String resumeId = (String) redisTemplate.opsForValue().get("FINSH_RESUME_CODE" + userId);
        if (StringUtils.isBlank(resumeId)) {
        }

        Boolean info = redisTemplate.hasKey(CodeVConstant.FINSH_PIINFO_CODE + userId);
        vo.setInfoFlag(!info);
        //求职意向是否填写
        Boolean intention = redisTemplate.hasKey(CodeVConstant.FINSH_INTENTION_CODE + userId);
        if (intention) {
            String o = (String) redisTemplate.opsForValue().get(CodeVConstant.FINSH_INTENTION_CODE + userId);

            vo.setIntentionFlag(false);
        } else {

            vo.setIntentionFlag(true);
        }
        Boolean edu = redisTemplate.hasKey(CodeVConstant.FINSH_EDU_CODE + userId);
        if (edu) {
            String o = (String) redisTemplate.opsForValue().get(CodeVConstant.FINSH_EDU_CODE + userId);

            vo.setEduFlag(false);
        } else {

            vo.setEduFlag(true);
        }
        Boolean work = redisTemplate.hasKey(CodeVConstant.FINSH_WORK_CODE + userId);
        if (work) {
            String o = (String) redisTemplate.opsForValue().get(CodeVConstant.FINSH_WORK_CODE + userId);

            vo.setWorkFlag(false);
        } else {

            vo.setWorkFlag(true);

        }
        return Result.ok(vo);
    }

    /**
     * 个人id查询
     *
     * @param id 数据id
     * @return
     */
    @GetMapping(value = "/queryById")
    @ApiOperation(value = "根据id查询", notes = "根据id查询")
    public Result<PiInfoVO> queryById(String id) {
        PiInfo piInfo = pinfoService
            .lambdaQuery()
            .eq(PiInfo::getUserId, id)
            .eq(PiInfo::getDelFlag, false)
            .one();
        if (piInfo == null) {
            throw new JeecgBootException("数据不存在");
        }
        PiInfoVO piInfoVO = piInfoConvert.toVO(piInfo);
        piInfoVO.setName(piInfo.getName());
        if (piInfo.getBirthday() != null) {
            piInfoVO.setAge(DateUtil.ageOfNow(piInfo.getBirthday()));
        }
        if (piInfo.getJobTime() != null) {
            piInfoVO.setWorkYears(AgeUtil.getAge(piInfo.getJobTime()));
        }
        String userId = piInfoVO.getUserId();
        LambdaUpdateWrapper<CvUserEduInfo> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(CvUserEduInfo::getUserId, userId).eq(CvUserEduInfo::getDelFlag, false);
        List<CvUserEduInfo> list = userEduInfoService.list(wrapper);
        Integer edu = 0;
        if (CollectionUtils.isNotEmpty(list)) {
            for (CvUserEduInfo eduInfo : list) {
                Integer level = eduInfo.getEduLevel();
                if (level > edu) {
                    edu = level;
                }
            }
        }
        piInfoVO.setPhotoId(piInfo.getPhotoId());
        piInfoVO.setEduLevel(eduLabelUtil.getEduLevel(edu));
        return Result.ok(piInfoVO);
    }

    /**
     * 个人基本信息添加
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/add")
    @AutoLog("个人基本信息-添加")
    @ApiOperation(value = "添加", notes = "添加")
    public Result<?> add(@RequestBody @Valid PiInfoParams params) {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        String username = sysUser.getUsername();
        PiInfo piInfo = piInfoConvert.toEntity(params);
        piInfo.setCreateBy(sysUser.getId());
        piInfo.setCreateTime(DateUtil.date());
        piInfo.setDelFlag(false);

        boolean saved = pinfoService.save(piInfo);
        return saved ? Result.ok() : Result.error("添加失败");
    }

    /**
     * 上传头像
     *
     * @param params
     * @return
     */
    @PostMapping("/updatePhoto")
    public Result<Object> updatePhoto(@RequestBody PiInfoParams params) {
        Assert.notBlank(params.getPhotoId(), "头像必传");
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        boolean update = this.pinfoService.lambdaUpdate()
            .eq(PiInfo::getId, params.getId())
            .eq(PiInfo::getUserId, sysUser.getId())
            .set(PiInfo::getPhotoId, params.getPhotoId())
            .update();
        Assert.isTrue(update, "上传失败");
        return Result.ok();
    }

    /**
     * 个人基本信息编辑
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/edit")
    @AutoLog("个人基本信息-编辑")
    @ApiOperation(value = "编辑", notes = "编辑")
    public Result<?> edit(@RequestBody @Valid PiInfoParams params) {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        PiInfo piInfo = piInfoConvert.toEntity(params);
        if (StrUtil.isBlank(params.getPhotoId())) {
            piInfo.setPhotoId(null);
        }
        piInfo.setIdNumber(params.getR6());
        piInfo.setUpdateBy(sysUser.getId());
        piInfo.setUpdateTime(DateUtil.date());
        piInfo.setPolitical(params.getPolitical());
        StringBuffer str2 = new StringBuffer();
        StringBuffer str3 = new StringBuffer();
        String[] townCode = params.getHomeTownCode();
        for (String s : townCode) {
            str2.append(s + ",");
        }

        String[] liveCityCode = params.getLiveCityCode();
        for (String s : liveCityCode) {
            str3.append(s + ",");
        }
        piInfo.setLiveCity(str3.toString());
        piInfo.setHomeTown(str2.toString());
        piInfo.setIdEntity(params.getIdentity());

        boolean updated = pinfoService.updateById(piInfo);

        Boolean hasKey = redisTemplate.hasKey(CodeVConstant.FINSH_PIINFO_CODE + sysUser.getId());
        if (hasKey && updated) {

            redisTemplate.delete(CodeVConstant.FINSH_PIINFO_CODE + sysUser.getId());
            if (0 != params.getIdentity()) {
                redisTemplate.delete(CodeVConstant.FINSH_WORK_CODE + sysUser.getId());
            }
        }
        if (updated) {
            if (StrUtil.isNotBlank(params.getName())) {
                List<CvResume> list = cvResumeService.lambdaQuery().eq(CvResume::getUserId, sysUser.getId())
                    .eq(CvResume::getDelFlag, false).list();
                if (CollectionUtils.isNotEmpty(list)) {
                    for (CvResume resume : list) {
                        Integer type = resume.getType();
                        Integer lanType = resume.getLanType();

                        if (1 == type) {
                            resume.setResumeName(params.getName() + "的附件简历");
                        }
                        if (0 == lanType && 0 == type) {
                            String name = resume.getResumeType() == 1 ? "的社招中文简历" : "的校招中文简历";
                            resume.setResumeName(params.getName() + name);
                        }
                        cvResumeService.saveOrUpdate(resume);

                    }
                }
            }
        }

        return updated ? Result.ok() : Result.error("编辑失败");
    }

    /**
     * 批量删除
     *
     * @param id 数据id
     * @return
     */
    @GetMapping(value = "/delete")
    @AutoLog("个人基本信息-批量删除")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    @RequiresPermissions("piInfo:delete")
    public Result delete(String[] id) {
        SysUser sysUser = (SysUser) SecurityUtils.getSubject();
        LambdaUpdateWrapper<PiInfo> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.in(PiInfo::getId, id)
            .set(PiInfo::getDelFlag, true)
            .set(PiInfo::getUpdateBy, sysUser.getUsername())
            .set(PiInfo::getUpdateTime, DateUtil.date());

        boolean deleted = pinfoService.update(updateWrapper);
        return deleted ? Result.ok() : Result.error("删除失败");
    }

    /**
     * 属性值是否重复
     *
     * @return
     */
    @Override
    @GetMapping("/propertyRepeat")
    @ApiOperation(value = "属性值是否重复", notes = "属性值是否重复")
    public Result propertyIsRepeat(@Valid AttributesValueParams params) {
        return super.propertyIsRepeat(params);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param params
     */
    @SneakyThrows
    @GetMapping(value = "/exportXls")
    @ApiOperation(value = "导出excel", notes = "导出excel")
    public Result exportXls(HttpServletRequest request, PiInfoParams params) {
        PiInfo piInfo = piInfoConvert.toEntity(params);
        piInfo.setDelFlag(false);
        QueryWrapper<PiInfo> queryWrapper = QueryGenerator.initQueryWrapper(piInfo, request.getParameterMap());
        List<PiInfo> data = pinfoService.list(queryWrapper);
        ExportParams exportParams = new ExportParams("个人基本信息", "个人基本信息");
        String url = super.exportXls(exportParams, PiInfoVO.class, piInfoConvert.toVO(data));
        return Result.ok((Object) url);
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping(value = "/importExcel")
    @ApiOperation(value = "通过excel导入数据", notes = "通过excel导入数据")
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, PiInfo.class);
    }

    /**
     * 个人首页各个数量统计
     *
     * @return
     */
    @GetMapping(value = "/getInfoNum")
    @AutoLog("个人首页数量统计栏")
    public Result<PiInfoNumVO> getInfoNum() {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        String username = sysUser.getId();
        PiInfoNumVO piInfoNumVO = new PiInfoNumVO();
        LambdaQueryWrapper<OpCollection> collectionWrapper = new LambdaQueryWrapper<>();
        collectionWrapper.eq(OpCollection::getDelFlag, false);
        collectionWrapper.eq(OpCollection::getUserId, username);
        int collect = collectionService.count(collectionWrapper);
        piInfoNumVO.setCollectNum(collect);
        LambdaQueryWrapper<OpEntryHistory> entryWrapper = new LambdaQueryWrapper<>();
        entryWrapper.eq(OpEntryHistory::getDelFlag, false);
        entryWrapper.eq(OpEntryHistory::getUserId, username);
        int entryNum = entryHistoryService.count(entryWrapper);
        piInfoNumVO.setEntryNum(entryNum);
        LambdaQueryWrapper<OpDeliveryHistory> deliveryWrapper = new LambdaQueryWrapper<>();
        deliveryWrapper.eq(OpDeliveryHistory::getDelFlag, false);
        deliveryWrapper.eq(OpDeliveryHistory::getUserId, username);
        int deliveryNum = deliveryHistoryService.count(deliveryWrapper);
        piInfoNumVO.setDeliveryNum(deliveryNum);
        LambdaQueryWrapper<OpInterviewHistory> interviewWrapper = new LambdaQueryWrapper<>();
        interviewWrapper.eq(OpInterviewHistory::getDelFlag, false);
        interviewWrapper.eq(OpInterviewHistory::getUserId, username);
        interviewWrapper.eq(OpInterviewHistory::getOutLineState, 1);
        interviewWrapper.eq(OpInterviewHistory::getOnLineState, 0);
        interviewWrapper.isNull(OpInterviewHistory::getViewResult);
        //2021年10月13日19:00:44 shengli修改----去除时间判断
        int interviewNum = interviewHistoryService.count(interviewWrapper);
        piInfoNumVO.setInterviewNum(interviewNum);
        return Result.ok(piInfoNumVO);
    }

    /**
     * 修改手机号
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/modify_phone")
    @AutoLog("修改手机号")
    public Result<?> modifyPhone(@RequestBody @Valid LoginUserParams params) {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        SysUser member = userService.lambdaQuery().eq(SysUser::getPhone, params.getMobile()).eq(SysUser::getDelFlag, false).one();
        String code = (String) redisTemplate.opsForValue().get("SEND_VERIFY_CODE_PERSON_:" + params.getMobile());
        if (sysUser.getPhone().equals(params.getMobile())) {
            Assert.isTrue(false, "新手机号不能与旧手机号相同");
        }
        if (member != null) {
            Assert.isTrue(StrUtil.equals(params.getMobile(), member.getPhone()), "该手机号已注册");
        }
        Assert.isTrue(StrUtil.equals(params.getVerifyCode(), code), "验证码错误");
        PiInfo piInfo = this.pinfoService.lambdaQuery().eq(PiInfo::getUserId, sysUser.getId()).one();
        piInfo.setPhone(params.getMobile());
        piInfo.setUsername(params.getMobile());
        boolean updated = pinfoService.updateById(piInfo);

        sysUser.setPhone(params.getMobile());
        sysUser.setUsername(params.getMobile());
        userService.updateById(sysUser);
        return updated ? Result.ok() : Result.error("修改失败");
    }

    /**
     * 消息-系统通知
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/announcement/list")
    @AutoLog("系统通告表-分页列表查询")
    @ApiOperation(value = "分页列表查询", notes = "分页列表查询")
    public Result<Page<SysPersonAnnouncementVO>> list(@RequestBody SysPersonAnnouncementParams params) {
        SysUser sysUser = (SysUser) SubjectUtils.getSubject();
        LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysAnnouncement::getDelFlag, false).eq(SysAnnouncement::getMsgType, "ALL").or(query -> query.eq(SysAnnouncement::getMsgType, "USER").eq(SysAnnouncement::getUserIds, sysUser.getId()));
        IPage<SysAnnouncement> page = sysAnnouncementService.page(params.page(), queryWrapper);
        //分页结果转换器
        Function<SysAnnouncement, SysPersonAnnouncementVO> fun = sysAnnouncement -> sysPersonAnnouncementConvert.toVO(sysAnnouncement);
        return Result.ok((Page) page.convert(fun));
    }

    /**
     * 心跳接口延长token有效期
     *
     * @param request
     * @param response
     */

    @RequestMapping(value = "/extendToken", method = RequestMethod.POST)
    public Result<?> extendToken(HttpServletRequest request,
                                 HttpServletResponse response) {
        try {

            String token = ServletUtil.getHeader(request, CommonConstant.TOKEN, Charsets.UTF_8);
            SysUser sysUser = (SysUser) SubjectUtils.getSubject();
            if (null == sysUser) {
                return Result.error("登陆失效,请重新登陆");
            }
            if (StrUtil.equals(profiles, DEV) || StrUtil.equals(profiles, TEST)) {
                redisTemplate.expire(CommonConstant.PREFIX_USER_TOKEN + token, SubjectUtils.EXPIR_DAY, TimeUnit.MINUTES);

            } else {
                redisTemplate.expire(CommonConstant.PREFIX_USER_TOKEN + token, 120, TimeUnit.MINUTES);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Result.ok();
    }

}
